package club.pchome.common.util.jwt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public abstract class StringUtil extends StringUtils {

	/**
	 * UUID
	 * @return
	 */
	public static String uuId(){
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/**
	 * 生成短信验证码
	 * @param length
	 * @return
	 */
	public static String randomCode(int length){
		 StringBuffer sb = new StringBuffer();
		 Random random = new Random();
		for (int i = 0; i < length ; i++) {
			int num =  random.nextInt(9);
			sb.append(num);
	    }
		return sb.toString();
	}

	/**
	 * 返回的结果集
	 * @param code
	 * @param msg
	 * @param data
	 * @return
	 */
	public static String resultMessage(int code, String msg, JSONObject data){
		JSONObject json = new JSONObject();
		json.put("code", code);
		json.put("msg", msg);
		json.put("data", data == null ? null : data);
		return JSON.toJSONString(json);
	}

	/**
	 * 返回的结果集
	 * @param code
	 * @param msg
	 * @param data
	 * @return
	 */
	public static String resultMessage(int code, String msg, Object data){
		JSONObject json = new JSONObject();
		json.put("code", code);
		json.put("msg", msg);
		json.put("data", data == null ? null : data);
		return JSON.toJSONString(json);
	}

	/**
	 * 返回的结果集
	 * @param code
	 * @param msg
	 * @param data
	 * @return
	 */
	public static String resultMessage(int code, String msg, JSONArray data){
		JSONObject json = new JSONObject();
		json.put("code", code);
		json.put("msg", msg);
		json.put("data", data == null ? null : data);
		return JSON.toJSONString(json);
	}

	/**
	 * 返回的结果集
	 * @param code
	 * @param msg
	 * @param data
	 * @return
	 */
	public static String resultMessage(int code, String msg){
		JSONObject json = new JSONObject();
		json.put("code", code);
		json.put("msg", msg);
		return JSON.toJSONString(json);
	}

	/**
	 * 替换特殊字符
	 * @param str
	 * @return
	 * @throws PatternSyntaxException
	 */
	public static String StringFilter(String str)   throws PatternSyntaxException {
       // 只允许字母和数字
       // String   regEx  =  "[^a-zA-Z0-9]";
       // 清除掉所有特殊字符
	   str = str.trim();
	   String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？? ]";
	   Pattern p   =   Pattern.compile(regEx);
	   Matcher m   =   p.matcher(str);
	   return   m.replaceAll("").trim();
   }

	 /**
     * 判断字符串是否是乱码
     *
     * @param strName 字符串
     * @return 是否是乱码
     */
    public static boolean isMessyCode(String strName) {
        Pattern p = Pattern.compile("\\s*|t*|r*|n*");
        Matcher m = p.matcher(strName);
        String after = m.replaceAll("");
        String temp = after.replaceAll("\\p{P}", "");
        char[] ch = temp.trim().toCharArray();
        float chLength = ch.length;
        float count = 0;
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (!Character.isLetterOrDigit(c)) {
                if (!isChinese(c)) {
                    count = count + 1;
                }
            }
        }
        float result = count / chLength;
        if (result > 0.4) {
            return true;
        } else {
            return false;
        }

    }

    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
            return true;
        }
        return false;
    }


	/**
	 * 判断是否为手机号码
	 * @param mobile
	 * @return
	 */
	public static boolean isMobile(String mobile) {
		Pattern p = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$"); // 验证手机号
		Matcher m = p.matcher(mobile);
		return m.matches();
	}

	public static void main(String[] args) throws UnsupportedEncodingException {
//		System.out.println(new String("?LILY?WU ? ".getBytes("UTF-8"),"GBK"));
//		System.out.println(encode("?LILY?WU ? "));
//		System.out.println(decode(encode("?LILY?WU ? ")));
		System.out.println(getRandomString(32));
	}






	/**
	 * @Title: randomClickNumber
	 * @Description: 随机数字 0 - 40
	 * @param @return
	 * @return int
	 * @throws
	 */
	public static int randomClickNumber() {
		int random = new Random().nextInt(40);
		if (random == 0) {
			random++;
		}
		return random;
	}

	/**
	 * 判断是否为数字
	 *
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		for (int i = str.length(); --i >= 0;) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}
	/**
	 * 判断是否为数字包含负数
	 *
	 * @param
	 * @return
	 */
	public static boolean isInteger(String value) {
		try {
			Integer.parseInt(value);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}

	/**
	 * @Title: getRandomString
	 * @Description: 随机字符串
	 * @param @param length
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * @Title: getJson
	 * @Description: 组装返回格式
	 * @param @param code
	 * @param @param msg
	 * @param @param date
	 * @param @return
	 * @return JSONObject
	 * @throws
	 */
	public static String getJson(int code, String msg, String data) {
		JSONObject json = new JSONObject();
		json.put("code", code);
		json.put("msg", msg);
		if (StringUtils.isNotEmpty(data)) {
			try {
				json.put("data", data);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return json.toJSONString();
	}


	/*
	 * 判断字符串是否包含一些字符 contains
	 */
	public static boolean containsString(String src, String dest) {
		boolean flag = false;
		if (src.contains(dest)) {
			flag = true;
		}
		return flag;
	}

	/*
	 * 判断字符串是否包含一些字符 indexOf
	 */
	public static boolean indexOfString(String src, String dest) {
		boolean flag = false;
		if (src.indexOf(dest) != -1) {
			flag = true;
		}
		return flag;
	}

	public static String EncoderByMd5(String str) {
		// 确定计算方法
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
			// 加密后的字符串
			BASE64Encoder base64en = new BASE64Encoder();
			// 加密后的字符串
			return base64en.encode(md5.digest(str.getBytes("utf-8")));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 编码
	 *
	 * @param src
	 * @return
	 */
	public static String encode(String src) {
		return new BASE64Encoder().encode(src.getBytes());
	}

	/**
	 * @param 解码
	 * @return
	 */
	public static String decode(String src) {
		try {
			byte[] data = new sun.misc.BASE64Decoder().decodeBuffer(src);
			return new String(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return src;
	}

	public static String getIpAddr(HttpServletRequest request) {
		String ipAddress = null;
		// ipAddress = this.getRequest().getRemoteAddr();
		ipAddress = request.getHeader("x-forwarded-for");
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0
				|| "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (Exception e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}

		}else{
			ipAddress = "127.0.0.0";
		}
		// 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
															// = 15
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}
	
	public static String getSource(HttpServletRequest request){
		String agent = request.getHeader("User-Agent");
		if(StringUtils.isEmpty(agent)){
			return "wz";
		}
		String userAgent = agent.trim().toLowerCase();
		if(userAgent.contains("iphone")){
			return  "iphone";
		}else if(userAgent.contains("iPod")){
			return "iPod";
		}else if(userAgent.contains("iPad")){
			return "iPad";
		}else if(userAgent.contains("windowsphone")){
			return "windowsphone";
		}else if(userAgent.contains("android")){
			return "android";
		}else if(userAgent.contains("nokian97")){
			return "nokian97";
		}else if(userAgent.contains("blackberry")){
			return "blackberry";
		}else if(userAgent.contains("hpwos")){
			return "hpwos";
		}else{
			return "wz";
		}
	}
	
	private static int randomNumber(){
		return new Random().nextInt(99999);
	}
	
	public static String createPaymentId(){
		return DateUtil.DateToString(new Date(), DateStyle.YYYYMMDDHHMMSS) + randomNumber();
	}
	
	// Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map  
    public static Map<String, Object> transBean2Map(Object obj) {
  
        if(obj == null){  
            return null;  
        }          
        Map<String, Object> map = new HashMap<String, Object>();
        try {  
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
  
                // 过滤class属性  
                if (!key.equals("class")) {  
                    // 得到property对应的getter方法  
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
  
                    map.put(key, value);  
                }  
  
            }  
        } catch (Exception e) {
            e.printStackTrace(); 
        }  
  
        return map;  
    }  
    
    public static TreeMap<String, String> transBeanTreeMap(Object obj) {
    	  
        if(obj == null){  
            return null;  
        }          
        TreeMap<String, String> map = new TreeMap<String, String>();
        try {  
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
  
                // 过滤class属性  
                if (!key.equals("class")) {  
                    // 得到property对应的getter方法  
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    map.put(key, String.valueOf(value));
                }  
  
            }  
        } catch (Exception e) {
            e.printStackTrace();
        }  
  
        return map;  
    }  
    
    public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
        if (map == null)  
            return null;    
  
        Object obj = beanClass.newInstance();
  
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();    
            if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){
                continue;    
            }    
  
            field.setAccessible(true);    
            field.set(obj, map.get(field.getName()));   
        }   
  
        return obj;    
    }    
  
    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if(obj == null){    
            return null;    
        }   
  
        Map<String, Object> map = new HashMap<String, Object>();
  
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);  
            map.put(field.getName(), field.get(obj));  
        }    
  
        return map;  
    } 
    
    // Map --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean  
    public static void transMap2Bean2(Map<String, String[]> map, Object obj) {
        if (map == null) {  
            return;  
        }  
        try {  
            BeanUtils.populate(obj, map);
        } catch (Exception e) {
            System.out.println("transMap2Bean2 Error " + e);
        }  
    }  
}
